#pragma once

#include "criticalsection.h"
#include "Handle.h"


class SharedReaderUniqueWriter
{
public:
    SharedReaderUniqueWriter(void);
    ~SharedReaderUniqueWriter(void);

public:
    void LockReader();
    void UnlockReader();

    void LockWriter();
    void UnlockWriter();

private:
    void Initialize();


private:
    syncLib::CriticalSection readerSection_;
    syncLib::CriticalSection writerSection_;
    unsigned int readersCount_;
    syncLib::Handle writingAllowedEvent_;
    bool isInitialized_;
};

class AutoWriterLocker : NonCopyable
{
public:
    explicit AutoWriterLocker(SharedReaderUniqueWriter& locker)
        :locker_(locker)
    {
        locker_.LockWriter();
    }

    ~AutoWriterLocker()
    {
        locker_.UnlockWriter();
    }

private:
    SharedReaderUniqueWriter& locker_;
};

class AutoReaderLocker : NonCopyable
{
public:
    explicit AutoReaderLocker(SharedReaderUniqueWriter& locker)
        :locker_(locker)
    {
        locker_.LockReader();
    }

    ~AutoReaderLocker()
    {
        locker_.UnlockReader();
    }

private:
    SharedReaderUniqueWriter& locker_;
};

